﻿using System.Collections.Generic;
using Cms.Application.Admin.Presenters;
using Cms.Application.Admin.Views;
using Cms.Domain;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Cms.Tests.Unit.Application.Admin.Presenters
{
    [TestClass]
    public class AdministratorsPresenterTests : BasePresenterTests
    {
        private Administrator _admin;
        private Mock<IAdministratorsView> _viewMock;
        private AdministratorGroup _administratorGroup;
        
        private void GeneralPrepare()
        {
            _admin = new Administrator() {ID = 1, Firstname = "Fredrik", Lastname = "Holm"};
            _administratorGroup = new AdministratorGroup { ID = 1 };
            _administratorGroup.Administrators.Add(_admin);
            _admin.Group = _administratorGroup;
            InitRepositoryFactoryMock();
            AdministratorRepositoryMock.Setup(a => a.GetAdministrator(1)).Returns(_admin);
            AdministratorRepositoryMock.Setup(a => a.GetAdministrators()).Returns(_administratorGroup.Administrators);
            _viewMock = new Mock<IAdministratorsView>();
            _viewMock.SetupAllProperties();
            _viewMock.Setup(v => v.AdministratorID).Returns(1);
            _viewMock.Setup(v => v.Localization).Returns("en-US");
            _viewMock.Setup(v => v.ContextTranslationFile).Returns("Admin/Translations/Administrators.xml");
        }
        
        [TestMethod]
        public void SetAdministrators_ThereAreTwoAdministrators_DisplayList()
        {
            GeneralPrepare();
            AdministratorsPresenter presenter = new AdministratorsPresenter(_viewMock.Object, FactoryMock.Object);
            presenter.SetAdministrators();
            AdministratorRepositoryMock.Verify(o => o.GetAdministrators());
            _viewMock.Verify(o => o.SetAdministrators(It.IsAny<IList<Administrator>>()));
        }
        
        [TestMethod]
        public void Delete_MoreThanOneAdministratorExists_Success()
        {
            GeneralPrepare();
            Administrator secondAdmin = new Administrator() {ID = 2};
            _administratorGroup.Administrators.Add(secondAdmin);
            secondAdmin.Group = _administratorGroup;
            AdministratorRepositoryMock.Setup(a => a.GetAdministrator(2)).Returns(secondAdmin);
            AdministratorsPresenter presenter = new AdministratorsPresenter(_viewMock.Object, FactoryMock.Object);
            presenter.Delete(2);
            Assert.IsTrue(secondAdmin.Deleted);
            AdministratorRepositoryMock.Verify(o => o.SaveAdministrator(secondAdmin));
        }

        [TestMethod]
        public void Delete_JustOneAdministratorExists_DisplayWarning()
        {
            GeneralPrepare();
            AdministratorsPresenter presenter = new AdministratorsPresenter(_viewMock.Object, FactoryMock.Object);
            presenter.Delete(1);
            _viewMock.Verify(o => o.DeleteLastAdministratorAlert(_admin.Fullname));
        }
        
        [TestMethod]
        public void Delete_MoreThanOneUserExistsButJustOneAdministrator_DisplayWarning()
        {
            GeneralPrepare();
            Administrator regularUser = new Administrator() { ID = 2 };
            AdministratorGroup users = new AdministratorGroup();
            users.Administrators.Add(regularUser);
            regularUser.Group = users;
            AdministratorRepositoryMock.Setup(a => a.GetAdministrator(2)).Returns(regularUser);
            AdministratorRepositoryMock.Setup(a => a.GetAdministrators()).Returns(new List<Administrator>(){_admin, regularUser});
            AdministratorsPresenter presenter = new AdministratorsPresenter(_viewMock.Object, FactoryMock.Object);
            presenter.Delete(1); // Delete the last admin
            _viewMock.Verify(o => o.DeleteLastAdministratorInTheAdminGroupAlert(_admin.Fullname));
        }
    }
}
